import 'package:campus_vision/extensions/iterable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_vlc_player/flutter_vlc_player.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../models/player/player_state.dart';
import 'device_providers.dart';

part 'video_player_provider.g.dart';

class VideoPlayerContext {
  final int deviceId;
  final int channelId;
  final VlcPlayerController? controller;
  final PlayerState playerState;
  final bool isActive; // 是否为当前激活窗口
  bool get hasController => controller != null;

  VideoPlayerContext({
    required this.deviceId,
    required this.channelId,
    this.controller,
    this.playerState = PlayerState.uninitialized,
    this.isActive = false,
  });

  VideoPlayerContext copyWith({
    PlayerState? playerState,
    bool? isActive,
    VlcPlayerController? controller,
  }) {
    return VideoPlayerContext(
      deviceId: deviceId,
      channelId: channelId,
      controller: controller ?? this.controller,
      playerState: playerState ?? this.playerState,
      isActive: isActive ?? this.isActive,
    );
  }
}

class VideoPlayerState extends _$VideoPlayerState {
  @override
  VideoPlayerContext build(int deviceId, int channelId) {
    final controller = _createController(deviceId, channelId);
    return VideoPlayerContext(
      deviceId: deviceId,
      channelId: channelId,
      controller: controller,
    );
  }

  VlcPlayerController? _createController(int deviceId, int channelId) {
    final channelList = ref.read(channelListProvider(deviceId)).value;

    if (channelList != null && channelList.isNotEmpty) {
      final channel = channelList.firstWhereOrNull((e) => e.id == channelId);
      if (channel != null) {
        final controller = VlcPlayerController.network(
          channel.url!,
          hwAcc: HwAcc.full,
          autoPlay: true,
        );
        debugPrint(
            "[player] create VLC controller ${deviceId}_$channelId ${channel.url}");
        controller.addListener(_handlePlayState);
        ref.onDispose(() async {
          debugPrint(
              "[player] dispose VLC controller ${channel.url} ${channel.id}");
          controller.removeListener(_handlePlayState);
          try {
            if (controller.value.isInitialized) {
              controller.removeListener(_handlePlayState);
              await controller.stopRendererScanning();
            }
          } catch (e) {
            debugPrint("⚠️ stopRendererScanning failed: $e");
            // 可选：记录日志或上报错误
          } finally {
            controller.dispose();
          }
        });
        return controller;
      }
    }
    return null;
  }

  void _handlePlayState() {
    final controller = state.controller;
    if (controller == null) return;
    PlayerState? playerState;
    if (controller.value.isPlaying) {
      playerState = PlayerState.playing;
    } else {
      switch (controller.value.playingState) {
        case PlayingState.initializing:
          playerState = PlayerState.uninitialized;
          break;
        case PlayingState.initialized:
          playerState = PlayerState.initializing;

          break;
        case PlayingState.stopped:
          break;
        case PlayingState.paused:
          playerState = PlayerState.paused;

          break;
        case PlayingState.ended:
          break;
        case PlayingState.buffering:
          playerState = PlayerState.buffering;

          break;
        case PlayingState.playing:
          playerState = PlayerState.playing;

          break;
        case PlayingState.recording:
          break;
        case PlayingState.error:
          playerState = PlayerState.error;
          break;
        default:
      }
    }
    if (playerState != null) {
      state = state.copyWith(playerState: playerState);
    }
  }

  void activate() => state = state.copyWith(isActive: true);
  void deactivate() => state = state.copyWith(isActive: false);

  void play() {
    state.controller?.play();
  }

  void pause() {
    state.controller?.pause();
  }

  Future<void> stop() async {
    await state.controller?.stop();
    await state.controller?.stopRendererScanning();
  }

  Future<void> reset() async {
    await stop();
    state = state.copyWith(controller: null);
  }

  void createController() {
    state = state.copyWith(controller: _createController(deviceId, channelId));
  }
}
